﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using HslCommunication;
using HslCommunication.Profinet.Melsec;

namespace AssemblyCYG.Tcp通讯
{
    public class MitsubishiTCP
    {
        //定义一个静态变量来保存类的实例
        public MelsecMcNet melsec_net = null;
        OperateResult result = null;

        public static bool bConnected = false;
        public static object lockObject = new object();
        public static object lockWriteObject = new object();
        public bool Connect(string ipString, string portString)
        {
            try
            {
                if(melsec_net != null)
                {
                    melsec_net.ConnectClose();
                    melsec_net = null;
                }

                // 连接
                System.Net.IPAddress address;
                if (!System.Net.IPAddress.TryParse(ipString, out address))
                {
                    return false;
                }

                int port;
                if (!int.TryParse(portString, out port))
                {
                    return false;
                }

                melsec_net = new MelsecMcNet(ipString,port);

                result = melsec_net.ConnectServer();

                bConnected = result.IsSuccess;

                if (!result.IsSuccess)
                {
                    return false;
                }
            }
            catch(Exception ex)
            {
                melsec_net = null;
                result = null;
                return false;
            }

            return true;
        }

        /// <summary>
        /// 读取double类型变量
        /// </summary>
        /// <param name="address"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public float ReadSingle(string address,ushort length)
        {
            float tmpDouble = 0.0f; 
            if (result != null && result.IsSuccess)
            {
                lock(lockObject)
                {
                    OperateResult<float[]> doubleResult = melsec_net.ReadFloat(address, length);
                    tmpDouble = doubleResult.Content[0];
                    return tmpDouble;
                }
            }

            return tmpDouble;
        }

        public short ReadInt16(string address,ushort length = 1)
        {
            short tmpInt = 0;
            if (result != null && result.IsSuccess)
            {
                lock (lockObject)
                {
                    OperateResult<short[]> intResult = melsec_net.ReadInt16(address, length);
                    tmpInt = intResult.Content[0];
                    return tmpInt;
                }
            }

            return tmpInt;
        }

        public short[] ReadInt16s(string address, ushort length)
        {
            short[] tmpInt = new short[length];
            for (int index = 0; index < length;index++)
            {
                tmpInt[index] = 0;
            }
            if (result != null && result.IsSuccess)
            {
                lock (lockObject)
                {
                    OperateResult<short[]> intResult = melsec_net.ReadInt16(address, length);
                    tmpInt = intResult.Content;
                    return tmpInt;
                }
            }

            return tmpInt;
        }

        public int ReadInt32(string address, ushort length = 1)
        {
            int tmpInt = 0;
            if (result != null && result.IsSuccess)
            {
                lock (lockObject)
                {
                    OperateResult<int[]> intResult = melsec_net.ReadInt32(address, length);
                    tmpInt = intResult.Content[0];
                    return tmpInt;
                }
            }

            return tmpInt;
        }

        /// <summary>
        /// 读取Bool类型变量
        /// </summary>
        /// <param name="address">地址信息</param>
        /// <returns></returns>
        public bool ReadBool(string address)
        {
            if (result != null && result.IsSuccess)
            {
                lock (lockObject)
                {
                    OperateResult<bool> boolResult = melsec_net.ReadBool(address);
                    return boolResult.Content;
                }
            }

            return false;
        }

        /// <summary>
        /// 读取Bool类型变量
        /// </summary>
        /// <param name="address">地址信息</param>
        /// <returns></returns>
        public bool[] ReadBool(string address,ushort length)
        {
            if (result != null && result.IsSuccess)
            {
                lock (lockObject)
                {
                    OperateResult<bool[]> boolResult = melsec_net.ReadBool(address, length);
                    return boolResult.Content;
                }
            }

            return new bool[3];
        }

        public string ReadString(string address, ushort length)
        {
            string tmpStr = "";
            if (result != null && result.IsSuccess)
            {
                lock (lockObject)
                {
                    OperateResult<string> strResult = melsec_net.ReadString(address, length);
                    tmpStr = strResult.Content;
                    return tmpStr;
                }
            }

            return tmpStr;
        }

        /// <summary>
        /// 写入 Bool 类型变量
        /// </summary>
        /// <param name="address">写入地址</param>
        /// <param name="value">数据</param>
        /// <returns></returns>
        public bool WriteBool(string address, bool[] value)
        {
            if (result == null || !result.IsSuccess)
            {
                return false;
            }

            lock (lockWriteObject)
            {
                OperateResult or = melsec_net.Write(address, value);
                return or.IsSuccess;
            }
        }

        /// <summary>
        /// 写入Int类型变量
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool WriteInt16(string address, short value)
        {
            if (result == null || !result.IsSuccess)
            {
                return false;
            }

            lock (lockWriteObject)
            {
                OperateResult or = melsec_net.Write(address, value);
                return or.IsSuccess;
            }
        }

        public bool WriteInt32(string address, int value)
        {
            if (result == null || !result.IsSuccess)
            {
                return false;
            }

            lock (lockWriteObject)
            {
                OperateResult or = melsec_net.Write(address, value);
                return or.IsSuccess;
            }
        }

        public bool WriteInt32s(string address, int[] value)
        {
            if (result == null || !result.IsSuccess)
            {
                return false;
            }

            lock (lockWriteObject)
            {
                OperateResult or = melsec_net.Write(address, value);
                return or.IsSuccess;
            }
        }

        public bool WriteInt32(string address, int[] value)
        {
            if (result == null || !result.IsSuccess)
            {
                return false;
            }

            lock (lockWriteObject)
            {
                OperateResult or = melsec_net.Write(address, value);
                return or.IsSuccess;
            }
        }


        /// <summary>
        /// 写入Int类型变量
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool WriteSingle(string address, float value)
        {
            if (result == null || !result.IsSuccess)
            {
                return false;
            }

            lock (lockWriteObject)
            {
                OperateResult or = melsec_net.Write(address, value);
                return or.IsSuccess;
            }
        }

        /// <summary>
        /// 写入Int类型变量
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool WriteSingles(string address, float[] value)
        {
            if (result == null || !result.IsSuccess)
            {
                return false;
            }

            lock (lockWriteObject)
            {
                OperateResult or = melsec_net.Write(address, value);
                return or.IsSuccess;
            }
        }

        public bool WriteString(string address,string value)
        {
            if (result == null || !result.IsSuccess)
            {
                return false;
            }

            lock (lockWriteObject)
            {
                OperateResult or = melsec_net.Write(address, value);
                return or.IsSuccess;
            }
        }


        /// <summary>
        /// 断开链接
        /// </summary>
        public void DisConnect()
        {
            if (melsec_net != null)
            {
                melsec_net.ConnectClose();
                bConnected = false;
                melsec_net = null;
            }
        }
    }
}
